home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / applic / ncsa / Mac / Telnet2.6 / prerelease / d5 / Telnet 2.6.1d5.src.sit.hqx / Telnet 2.6.1d5 src / source / wdef / wdefpatch.c oldauth next >
Encoding:
Text File  |  1994-06-22  |  12.9 KB  |  492 lines

  1. /*******************************************
  2.  
  3.     WDEF Patcher
  4.     Steve Falkenburg MacDTS
  5.     ⌐1991 Apple Computer
  6.     
  7.     This snippet shows how you can add a simple extra part to a WDEF without
  8.     writing an entire WDEF.  It also shows how to access the new part via
  9.     FindWindow().
  10.     
  11.     Roberto Avanzi (independent programmer), June 18, 1992
  12.     Added support for tracking the extra part, in a way similar to the one used
  13.     by the system.
  14.     given back to Apple as an enhanced snippet (mmmh, sounds quite absurd)
  15.     
  16.     6/1/92    SJF        fixed a5 problem in WDEF patch (StripAddress is glue, and a5 wasn't set up)
  17.     6/1/92    SJF        fixed varCode bug that made zoom boxes not work (masked out high 8 bits)
  18.     
  19. *******************************************/
  20.  
  21. #ifdef MPW
  22. #pragma segment 22
  23. #endif
  24.  
  25. #include "TelnetHeader.h"
  26. #include <GestaltEqu.h>
  27. #ifdef THINK_C
  28. #include <SysEqu.h>
  29. #endif
  30. #include "wind.h"
  31. #include "wdefpatch.proto.h"
  32. #ifdef newauth
  33. #include "tnae.h"
  34. #endif
  35.  
  36. static void drawicon(short id, Rect *dest);
  37.  
  38. /* 931112, ragge, NADA, KTH */
  39. static void drawSize(Rect *wSize, WindowPtr window);
  40.  
  41. /* add 2 to this when checking with FindWindow() ! */
  42.  
  43. #define kOurHit    32
  44.  
  45.  
  46. /* 
  47.  * this struct allows us to insert a WDEF patch safely.  It contains a jump instruction
  48.  * and stores the old handle to the WDEF
  49.  */
  50.  
  51. typedef struct {
  52. #ifdef __powerpc__
  53.     RoutineDescriptor rd;
  54. #else
  55.     short jmpInst;
  56.     ProcPtr patchAddr;
  57. #endif
  58.     Handle oldAddr;
  59.     Boolean partState;    /* roberto avanzi jun 18 1992 */
  60.     long ourA5;
  61.     struct WindRec *tw;
  62. } WDEFPatch, *WDEFPatchPtr, **WDEFPatchHndl;
  63.  
  64.  
  65. /* 
  66.  * RePatchWindowWDEF
  67.  * this adjusts the tw pointer for a patched window
  68.  * We have to do this since the tw for a window can change when other
  69.  * windows are killed.
  70.  */
  71. void RePatchWindowWDEF (WindowPtr window, struct WindRec *tw)
  72. {
  73.     WDEFPatchHndl wdPatch;
  74.  
  75.     wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
  76.     (**wdPatch).tw = tw;
  77. }
  78.  
  79.  
  80. /*
  81.  * GetPatchStuffHandle
  82.  * This returns the handle to our patch block so we can release it
  83.  * when killing windows. The tw is verified to insure that this
  84.  * window is really patched.
  85.  */
  86. Handle GetPatchStuffHandle (WindowPtr window, struct WindRec *tw)
  87. {
  88.     WDEFPatchHndl wdPatch;
  89.  
  90.     wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
  91.     if ((**wdPatch).tw == tw)
  92.         return ((Handle)wdPatch);
  93.     else
  94.         return ((Handle)0);
  95. }
  96.  
  97.  
  98. #ifdef __powerpc__
  99. enum {
  100.     uppMyWDEFPatch = kPascalStackBased
  101.         | RESULT_SIZE(SIZE_CODE(sizeof(long)))
  102.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short)))
  103.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr)))
  104.         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short)))
  105.         | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
  106. };
  107. #endif
  108.  
  109. pascal long MyWDEFPatch (short varCode, WindowPtr window, short message, long param)
  110. {
  111.     WDEFPatchHndl wdPatch;
  112.     pascal long (*wdefProc)(short varCode,WindowPtr window,short message,long param);
  113.     Handle oldWDEF;
  114.     long result;
  115.     Rect ourRect,ourElementRect;
  116.     GrafPtr    savePort;
  117.     GrafPtr aPort;
  118.     RgnHandle aRgn;
  119.     Rect aRect;
  120.     struct WindRec *tw;
  121.     long appA5, saveA5;
  122.     
  123.     wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
  124.     appA5 = (**wdPatch).ourA5;
  125.     saveA5 = SetA5(appA5);
  126.  
  127.     ourRect = (**((WindowPeek)window)->strucRgn).rgnBBox;
  128.     /* our 16x16 rectangle */
  129.     SetRect(&ourElementRect,ourRect.right-42,ourRect.top+1,ourRect.right-26,ourRect.top+17);
  130.     
  131.     tw = (**wdPatch).tw;
  132.  
  133.     oldWDEF = (**wdPatch).oldAddr;
  134.     HLock(oldWDEF);
  135.     wdefProc = (void *)*oldWDEF;
  136.     wdefProc = (void *)StripAddress(wdefProc);
  137.  
  138.     /* 
  139.      * now, folks, WHY do I check it, u'll ask me ? Heh, it's a funny quirk in
  140.      * the sys WDEF (at least, sys 7's, dunno whattabout older ones) .
  141.      * Suppose You click once in the grow icon and DO NOT resize the window.
  142.      * (remember, just click and do not move the mouse in the meantime).
  143.      * Then you click on the added part. That part is tracked in the right way,
  144.      *                             *    BUT   *
  145.      * ALSO the zoom box gets hilited. Dunno why should happen, but It's a lot
  146.      * of FUN. Sadly, cannot find its place in any useful app. Therefore we
  147.      * do this check.
  148.      * APPLE says: if you write your own WDEF and receive unknown messages, do not
  149.      *             do anything. pass along and do NOTHING.
  150.      * APPLE does: we get something new ? therefore we process it anyway, just to
  151.      *             keep developers writing workarounds and keep their minds afresh.
  152.      * What else can we say ? Thanks !!!!! (Roberto Avanzi june 19, 1992)
  153.      */
  154.     if ( (message == wDraw) ? (((short)param) != kOurHit ) : true ) {
  155. #ifdef __powerpc__
  156.         result = CallUniversalProc((UniversalProcPtr)wdefProc, uppMyWDEFPatch, varCode, window, message, param);
  157. #else
  158.         result = (wdefProc)(varCode,window,message,param);
  159. #endif
  160.     }
  161.  
  162.     if (((WindowPeek)window)->visible)
  163.     if (((WindowPeek)window)->hilited)
  164.     {
  165.         switch (message) {
  166.             case wDraw:
  167.                 GetPort(&savePort);
  168.                 GetWMgrPort(&aPort);
  169.                 SetPort(aPort);
  170.                 aRgn = NewRgn();
  171.                 GetClip(aRgn);
  172.                 SetRect(&aRect,-32000,-32000,32000,32000);
  173.                 ClipRect(&aRect);
  174.                 switch ( (short) param ) {    // Roberto Avanzi 18-06-1992: support for 
  175.                                             // tracking of the new part
  176.                     case 0:
  177.                         (**wdPatch).partState = false;
  178.  
  179.                     case kOurHit:
  180.                         PenNormal();                            // draw our part
  181.     
  182. #ifdef newauth
  183.                          if (tw->aedata != NULL) {
  184.                             tnParams *ae = (tnParams *)tw->aedata;
  185.  
  186.                              if (ae->encrypting || ae->decrypting) {
  187.                                  /* 
  188.                                   * erase 18 x 11. This gives us a 1 pixel margin
  189.                                   * on the left and right, and matches the mask that
  190.                                   * we're using in our crsr resources.
  191.                                   */
  192.                                  InsetRect(&ourElementRect, -1, 0);
  193.                                  ourElementRect.top += 3;
  194.                                  ourElementRect.bottom -= 2;
  195.                                  EraseRect(&ourElementRect);
  196.                                  ourElementRect.top -= 3;
  197.                                  ourElementRect.bottom += 2;
  198.                                  InsetRect(&ourElementRect, 1, 0);
  199.                              }                        
  200.                              if (ae->encrypting && ae->decrypting)
  201.                                  drawicon(lockcrsr, &ourElementRect);
  202.                              else if (ae->encrypting)
  203.                                  drawicon(rightcrsr, &ourElementRect);
  204.                              else if (ae->decrypting)
  205.                                  drawicon(leftcrsr, &ourElementRect);
  206.                          }
  207. #else
  208.                          if (tw->edata != NULL) {
  209.                              if (tw->edata->encrypt_output || tw->edata->decrypt_input) {
  210.                                  /* 
  211.                                   * erase 18 x 11. This gives us a 1 pixel margin
  212.                                   * on the left and right, and matches the mask that
  213.                                   * we're using in our crsr resources.
  214.                                   */
  215.                                  InsetRect(&ourElementRect, -1, 0);
  216.                                  ourElementRect.top += 3;
  217.                                  ourElementRect.bottom -= 2;
  218.                                  EraseRect(&ourElementRect);
  219.                                  ourElementRect.top -= 3;
  220.                                  ourElementRect.bottom += 2;
  221.                                  InsetRect(&ourElementRect, 1, 0);
  222.                              }                        
  223.                              if (tw->edata->encrypt_output && tw->edata->decrypt_input)
  224.                                  drawicon(lockcrsr, &ourElementRect);
  225.                              else if (tw->edata->encrypt_output)
  226.                                  drawicon(rightcrsr, &ourElementRect);
  227.                              else if (tw->edata->decrypt_input)
  228.                                  drawicon(leftcrsr, &ourElementRect);
  229.                          }
  230. #endif
  231.                         break;
  232.                         
  233.                     default:
  234.                         break;
  235.                 }
  236.                 SetClip(aRgn);
  237.                 DisposeRgn(aRgn);
  238.                 SetPort(savePort);
  239.                 break;
  240.  
  241.                 // removed this test so that one can move the window
  242.                 // also when clicking on the icon area.
  243.                 // 931112, ragge, NADA, KTH
  244. #ifdef NOTDEF
  245.             case wHit:
  246.                 hitPt = (Point *)¶m;                    // hit test our part
  247.                 if (PtInRect(*hitPt,&ourElementRect))
  248.                 {
  249.                     //result =  kOurHit;
  250.                 }
  251.                 break;
  252. #endif
  253.             
  254.             case wGrow:        /* 931112, ragge, NADA, KTH */
  255.                 drawSize((Rect *) param, window);
  256.                 break;
  257.  
  258.             default:
  259.                 break;
  260.         }    // switch
  261.     }    //    if hilited (otherwise we dont see the new box, addition by Roberto Avanzi)
  262.     HUnlock(oldWDEF);
  263.     
  264.     SetA5(saveA5);
  265.     
  266.     return result;
  267. }
  268.  
  269.  
  270. #ifdef __powerpc__
  271. RoutineDescriptor MyWDEFPatchUniversal = BUILD_ROUTINE_DESCRIPTOR(uppMyWDEFPatch, MyWDEFPatch);
  272. #endif
  273.  
  274. /* 
  275.  * this installs the WDEF patch into a window 
  276.  */
  277. void PatchWindowWDEF (WindowPtr window, struct WindRec *tw)
  278. {
  279.     WDEFPatchHndl wdefHndl;
  280.     WDEFPatchPtr wdefPatch;
  281.     Handle oldAddr;
  282.     unsigned long wdefEntry;
  283.     
  284.     wdefHndl = (WDEFPatchHndl)NewHandle(sizeof(WDEFPatch));
  285.  
  286.     oldAddr = ((WindowPeek)window)->windowDefProc;
  287.     if (GetMMUMode()) // 32-bit
  288.         wdefEntry = (unsigned long)wdefHndl;
  289.     else
  290.         wdefEntry = (unsigned long)StripAddress(wdefHndl) | ((unsigned long)oldAddr&0xff000000);
  291.  
  292.     HLock((Handle)wdefHndl);
  293.     wdefPatch = *wdefHndl;
  294.     wdefPatch->oldAddr = oldAddr;
  295. #ifdef __powerpc__
  296.     BlockMove(&MyWDEFPatchUniversal, &wdefPatch->rd, sizeof(wdefPatch->rd));
  297. #else
  298.     wdefPatch->jmpInst = 0x4ef9; /*JMP*/
  299.     wdefPatch->patchAddr = (ProcPtr)MyWDEFPatch;
  300. #endif
  301.     wdefPatch->ourA5 = (long)LMGetCurrentA5();        /* Use universal access (RW) */
  302.     wdefPatch->tw = tw;
  303.  
  304.     HUnlock((Handle)wdefHndl);
  305.  
  306.     ((WindowPeek)window)->windowDefProc = (Handle)wdefEntry;
  307. }
  308.  
  309.  
  310. /*
  311.  * drawicon
  312.  */
  313. void drawicon (short id, Rect *dest)
  314. {
  315.     long qdv;
  316.     Handle ih = 0;
  317.     Rect source_rect;
  318.     BitMap mask_bitmap;
  319.     GrafPtr local_port;
  320.     PixMap *pm;
  321.     Ptr colormap;
  322.     CCrsr *ccrsr;
  323.     BitMap src_bitmap;
  324.  
  325.     GetPort(&local_port);
  326.  
  327.     ih = GetResource ('crsr', id);                /* color cursor */
  328.     if (!ih)
  329.         return;
  330.     DetachResource(ih);        /* ... need to save handle somewhere ... */
  331.     HLock(ih);                /* ... to avoid reloading the resource all the time */
  332.  
  333.     /* 
  334.      * Set source Rect and intialize source BitMaps. 
  335.      * A few PixMap fields must be munged;
  336.      */
  337.     SetRect (&source_rect, 0, 0, 16, 16);
  338.     
  339.     ccrsr = (CCrsr *)(*ih);
  340.  
  341.     mask_bitmap.bounds = source_rect;
  342.     mask_bitmap.rowBytes = 2;
  343.     mask_bitmap.baseAddr = (Ptr)&ccrsr->crsrMask; /* (Ptr)(((Byte *)(*ih)) + 52); */
  344.     
  345.     /*
  346.      * if gestalt fails or no color quickdraw, just use the b/w bitmap.
  347.      */
  348.     if (Gestalt(gestaltQuickdrawVersion, &qdv) || ((qdv & gestalt32BitQD) == 0)) {
  349.         src_bitmap.bounds = source_rect;
  350.         src_bitmap.rowBytes = 2;
  351.         src_bitmap.baseAddr = (Ptr)&ccrsr->crsr1Data;
  352.         CopyBits(&src_bitmap, &(local_port->portBits), &source_rect, dest,
  353.                  srcCopy, nil);    
  354.     } else {
  355.         pm = (PixMap *) ((unsigned char *)ccrsr + (long)ccrsr->crsrMap);
  356.         pm->baseAddr = (Ptr) ((unsigned char *)ccrsr + (long)ccrsr->crsrData);
  357.             colormap = (Ptr) ((unsigned char *)ccrsr + (long)pm->pmTable);
  358.         pm->pmTable = (CTabHandle) &colormap;        /* handle to colormap */
  359.  
  360.         /* 
  361.          * Draw the crsr using its mask. 
  362.          * Do we need the mask ??? ...
  363.          */
  364.         CopyMask((BitMap *)pm, &mask_bitmap, &(local_port->portBits),
  365.                  &source_rect, &source_rect, dest);
  366.     }
  367.  
  368.     HUnlock(ih);
  369.     ReleaseResource((Handle)ih);
  370.     DisposHandle((Handle)ih);
  371. }
  372.  
  373. /* 931112, ragge, NADA, KTH */
  374. #define    HOFFSET    2
  375. #define VOFFSET    2
  376. static Rect gGrowTextBox;
  377. static Rect gGrowTextBoxInset;
  378. Boolean gDoGrowSize = false;
  379. static struct growSavedStruct {
  380.     Point charSize;
  381.     Point charInset;
  382.     Boolean eraseIt;
  383.  
  384.     PenState    savedPen;
  385.     short txFont;
  386.     Style txFace;
  387.     short txMode;
  388.     short txSize;
  389. } gGrowSaved;
  390.  
  391. /* 931112, ragge, NADA, KTH */
  392. void setupForGrow(WindowPtr window, short hCharInset, short vCharInset, short hCharSize, short vCharSize)
  393. {
  394.     GrafPtr    savedPort;
  395.     FontInfo fInfo;
  396.  
  397.     GetPort(&savedPort);
  398.     SetPort(window);
  399.         
  400.     gGrowSaved.charSize.h = hCharSize;
  401.     gGrowSaved.charSize.v = vCharSize;
  402.     gGrowSaved.charInset.h = hCharInset;
  403.     gGrowSaved.charInset.v = vCharInset;
  404.  
  405.     if(gGrowSaved.charSize.h == 0)    // don't want zero-div
  406.         gGrowSaved.charSize.h = 1;
  407.     if(gGrowSaved.charSize.v == 0)
  408.         gGrowSaved.charSize.v = 1;
  409.         
  410.     gGrowSaved.eraseIt = false;
  411.     
  412.     GetPenState(&gGrowSaved.savedPen);
  413.     
  414.     gGrowSaved.txFont = window->txFont;
  415.     gGrowSaved.txFace = window->txFace;
  416.     gGrowSaved.txMode = window->txMode;
  417.     gGrowSaved.txSize = window->txSize;
  418.  
  419.     PenNormal();
  420.     TextFont(1);
  421.     TextSize(9);
  422.     TextFace(0);
  423.     TextMode(srcCopy);
  424.     
  425.     GetFontInfo(&fInfo);
  426.  
  427.     gGrowTextBox.top = VOFFSET;
  428.     gGrowTextBox.left = HOFFSET;
  429.     gGrowTextBox.bottom = VOFFSET + fInfo.ascent + fInfo.descent + fInfo.leading + 3;    // Yes, 3!
  430.     gGrowTextBox.right = HOFFSET + StringWidth("\p000 * 000") + 6;
  431.     gGrowTextBoxInset = gGrowTextBox;
  432.     InsetRect(&gGrowTextBoxInset, 1, 1);
  433.     
  434.     gDoGrowSize = true;
  435.     
  436.     SetPort(savedPort);
  437. }
  438.  
  439. /* 931112, ragge, NADA, KTH */
  440. void cleanupForGrow(WindowPtr window)
  441. {
  442.     GrafPtr    savedPort;
  443.     GetPort(&savedPort);
  444.     SetPort(window);
  445.     
  446.     gDoGrowSize = false;
  447.     
  448.     InvalRect(&gGrowTextBox);
  449.     
  450.     SetPenState(&gGrowSaved.savedPen);
  451.     
  452.     window->txFont = gGrowSaved.txFont;
  453.     window->txFace = gGrowSaved.txFace;
  454.     window->txMode = gGrowSaved.txMode;
  455.     window->txSize = gGrowSaved.txSize;
  456.     
  457.     SetPort(savedPort);
  458. }
  459.  
  460. /* 931112, ragge, NADA, KTH */
  461. void drawSize(Rect *wSize, WindowPtr window)
  462. {
  463.     unsigned char string[50], yValLen;
  464.     GrafPtr savedPort;
  465.     
  466.     if(!gDoGrowSize)
  467.         return;
  468.  
  469.     GetPort(&savedPort);
  470.     SetPort(window);
  471.     
  472.     if(!gGrowSaved.eraseIt) {
  473.         NumToString((wSize->right - wSize->left - 15 - gGrowSaved.charInset.h) / gGrowSaved.charSize.h, string);
  474.         string[++string[0]] = ' ';
  475.         string[++string[0]] = '*';
  476.         NumToString((wSize->bottom - wSize->top - 15 - gGrowSaved.charInset.v) / gGrowSaved.charSize.v, string + string[0] + 1);
  477.         yValLen = string[string[0] + 1];
  478.         string[++string[0]] = ' ';
  479.         string[0] += yValLen;
  480.         TextBox(string + 1, string[0], &gGrowTextBoxInset, 1);
  481.         FrameRect(&gGrowTextBox);
  482.     } else {
  483.         Rect rGlob = gGrowTextBox;
  484.         LocalToGlobal((Point *) &(rGlob.top));
  485.         LocalToGlobal((Point *) &(rGlob.bottom));
  486.     }
  487.     
  488.     gGrowSaved.eraseIt = !gGrowSaved.eraseIt;
  489.  
  490.     SetPort(savedPort);
  491. }
  492.